package com.mcjtf.prefix.bridge;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import com.mcjtf.prefix.PrefixManager;
import com.mcjtf.prefix.api.event.PrefixChangeEvent;
import com.mcjtf.prefix.model.User;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;

public class NameTagHook implements Listener {
    private PrefixManager main;
    private ProtocolManager protocol;

    public NameTagHook() {
        main = PrefixManager.getInstance();
        protocol = ProtocolLibrary.getProtocolManager();
        main.getServer().getPluginManager().registerEvents(this, main);
    }

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        main.getServer().getScheduler().runTaskLater(main, () -> {
            User user = main.getPrefixService().getUser(event.getPlayer().getName());
            if (user == null) {
                return;
            }
            sendNameTagJoin(event.getPlayer(), user.getPrefix(), user.getSuffix());
        }, 30L);
    }

    @EventHandler
    public void onPrefixChange(PrefixChangeEvent event) {
        User user = main.getPrefixService().getUser(event.getPlayer().getName());
        if (user == null) {
            return;
        }
        sendNameTagChange(event.getPlayer(), user.getPrefix(), user.getSuffix());
    }

    public void sendNameTagChange(Player player, String prefix, String suffix) {
        PacketContainer packet = getPlayerNameTagPacket(player, prefix, suffix);
        main.getServer().getOnlinePlayers().forEach((line) -> {
            sendPacket(line, packet);
        });
    }

    public void sendNameTagJoin(Player player, String prefix, String suffix) {
        PacketContainer packet = getPlayerNameTagPacket(player, prefix, suffix);
        main.getServer().getOnlinePlayers().forEach((line) -> {
            sendPacket(line, packet);
            User user = main.getPrefixService().getUser(line.getName());
            if (user == null) {
                return;
            }
            PacketContainer linePacket = getPlayerNameTagPacket(line, user.getPrefix(), user.getSuffix());
            sendPacket(player, linePacket);
        });
    }

    public PacketContainer getPlayerNameTagPacket(Player player, String prefix, String suffix) {
        PacketContainer fakeTeam = new PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM);
        String name = UUID.randomUUID().toString().substring(0, 16);
        fakeTeam.getStrings().write(0, name);
        fakeTeam.getIntegers().write(0, 0);
        fakeTeam.getStrings().write(1, player.getName());
        fakeTeam.getStrings().write(2, prefix);
        fakeTeam.getStrings().write(3, suffix);
        fakeTeam.getIntegers().write(1, 0);
        fakeTeam.getIntegers().write(2, 6);
        fakeTeam.getSpecificModifier(Collection.class).write(0, Arrays.asList(new String[]{player.getName()}));
        return fakeTeam;
    }

    public void sendPacket(Player player, PacketContainer packet) {
        try {
            protocol.sendServerPacket(player, packet, false);
        } catch (InvocationTargetException e) {
            main.getLogger().info(e.getMessage());
        }
    }
}
